package com.zxjbyte.yiyi.framework.common.constant;

import com.zxjbyte.yiyi.framework.common.core.CacheKey;

import java.time.Duration;
import java.util.StringJoiner;

/**
 * Redis Key 定义与构建工具
 *
 * 支持模块级前缀，统一 Key 规范：
 * 格式：yiyi_boot[:module][:业务Key...]
 *
 * 示例：
 *  RedisKeyDefine.key("dict", 1)
 *   -> yiyi_boot:dict:1
 *
 *  RedisKeyDefine.module("system").key("dict", 1)
 *   -> yiyi_boot:system:dict:1
 *
 *  RedisKeyDefine.module("messaging").key(Duration.ofHours(1), "msg", userId)
 *   -> yiyi_boot:messaging:msg:{userId}
 * @Author zhangxingjia
 * @Date 2023/4/3 14:10
 * @Version: 1.0
 */
public final class RedisKeyDefine {

    private RedisKeyDefine(){};

    /** 项目前缀 */
    private static final String BASE_PREFIX = "yiyi_boot";

    // ========== 业务模块 Key 定义 ==========
    /**
     * 模块常量定义
     */
    public static final class Modules {
        public static final String OSS_CONFIG = "oss:config";
        public static final String DICT = "dict";
        public static final String DEV_CONFIG = "dev_config";
        public static final String CAPTCHA = "captcha";

        private Modules() {}
    }

    // =================== 静态方法 ===================

    /** 普通 key（无模块） */
    public static String buildKey(Object... parts) {
        return buildKeyInternal(null, parts);
    }

    /** 带过期时间 key（无模块） */
    public static CacheKey buildKey(Duration expire, Object... parts) {
        return new CacheKey(buildKeyInternal(null, parts), expire);
    }

    /** 模块化构建器 */
    public static ModuleKeyBuilder module(String moduleName) {
        return new ModuleKeyBuilder(moduleName);
    }


    // =================== 内部逻辑 ===================

    private static String buildKeyInternal(String module, Object... parts) {
        StringJoiner joiner = new StringJoiner(":");
        joiner.add(BASE_PREFIX);

        if (module != null && !module.isEmpty()) {
            joiner.add(module);
        }

        if (parts != null) {
            for (Object part : parts) {
                if (part != null && !part.toString().isEmpty()) {
                    joiner.add(part.toString());
                }
            }
        }

        return joiner.toString();
    }

    // =================== 模块构建器 ===================

    public static class ModuleKeyBuilder {
        private final String module;

        private ModuleKeyBuilder(String module) {
            this.module = module;
        }

        public String buildKey(Object... parts) {
            return buildKeyInternal(module, parts);
        }

        public CacheKey buildKey(Duration expire, Object... parts) {
            return new CacheKey(buildKeyInternal(module, parts), expire);
        }
    }
}
